/* implements the functions defined in display.h */

#include "display.h"

/* prints a string on the LCD display. Returns SUCCESS if the operation is successful, FAILURE otherwise. Data must be a null terminated string  */

int32_t print_lcd(const char* data){
  if(data == NULL)
    return FAILURE;
  malta_lcd_print(data);
  return SUCCESS;
}


/* prints the string data on the tty0 console. Returns SUCCESS if the operation is sucessful, FAILURE otherwise. data must be a null-terminated string. */
int32_t print_string(const char* data){
  PCB* caller = get_running();
  if(caller == NULL)
    return FAILURE;
  int32_t r;
  //we check if there is something to print
  if(data == NULL)
    return FAILURE;
  if(data[0] == '\0')
    return SUCCESS; //this is not an error case. 
  //requesting the device
  r = get_uart(caller);
  if(r == SUCCESS){
    //device acquired
    //the caller is blocked until the I/O is done
    block_pcb(caller);
    //this process is doing IO
    pcb_set_state(caller, DOING_IO_UART_STATE);
    //sets UART global variables
    set_printing_mode(data);
    //starts the printing
    print();
    return 2; //fake return value
    //the real return value will be inserted directly into the saved registers at the end of the printing
  }else
    return r; //either an error occured or the caller is now waiting in the device queue
}

/* reads a string from the user using the tty0 device. It reads until the user presses enter or up to length-1 characters. The characters read are put in data and the null character is appended at the end. It returns SUCCESS if the operation is successful, FAILURE otherwise. It also prints what has been read. */
int32_t read_string(char* data, int32_t length){
  PCB* caller = get_running();
  if(caller == NULL)
    return FAILURE;
  int32_t r;
  //we check we can store data somewhere
  if(data == NULL || length == 0)
    return FAILURE; //an empty string would mean a string without '\0', impossible
  if(length == 1){
    data[0] = '\0';
    return SUCCESS; //this is not an error case. 
  }
  //requesting the device
  r = get_uart(caller);
  if(r == SUCCESS){
    //device acquired
    //blocks the caller
    block_pcb(caller);
    //this process is doing IO
    pcb_set_state(caller, DOING_IO_UART_STATE);
    //sets the correct mode
    set_reading_mode(data, length);
    //starts reading
    read();
    return 2; //fake return value
  }else
    return r; 
}
